package com.lx.constant.segment.query;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.lx.constant.consts.SqlFormatConstant;
import com.lx.constant.enums.ColumnKeyWorldEnum;
import com.lx.constant.segment.ChildConditionSegment;
import com.lx.constant.segment.Segment;
import com.lx.wrapper.AbstractCommonConditionWrapper;
import com.lx.wrapper.AbstractWrapper;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.JoinColumn;
import java.lang.reflect.Field;
import java.util.Objects;
import java.util.TreeSet;

/**
 * 列名语句
 *
 * @author lx
 * @create 2022/12/9 14:09
 **/
@Setter
@Getter
public class ColumnSegment extends ChildConditionSegment {

    /**
     * 查询列别名
     */
    private String aliasName;

    /**
     * 列扩展属性补充列表
     */
    private final TreeSet<ColumnKeyWorldEnum> columnExtendList = new TreeSet<>((v1, v2) -> {
        if (v1 != v2 && v1.getGrade() == v2.getGrade()) {
            throw new IllegalArgumentException("相同属性的列名关键字无法重叠组合!");
        }
        return v2.getGrade() - v1.getGrade();
    });

    @Override
    public String convertSegmentToQL(AbstractWrapper parentWrapper, AbstractWrapper thisWrapper, boolean isHQL) {
        String columnName, aliasName = getAliasName();

        AbstractCommonConditionWrapper childWrapper = getChildConditionWrapper();
        if (childWrapper != null) {
            //子查询语句执行. (可以支持不设置别名)
            columnName = String.format(SqlFormatConstant.PARENTHESES_FORMAT, childWrapper.getCompleteQL(isHQL, parentWrapper));
        } else {
            columnName = super.convertSegmentToQL(parentWrapper, thisWrapper, isHQL);

            //如果Field存在且用户未生成别名,则需要判断JoinColumn注解是否存在,否则HQL自动校验无法通过.
            Field columnField = getColumnField();
            if (columnField != null && StrUtil.isEmpty(aliasName)) {
                JoinColumn joinColumn = columnField.getAnnotation(JoinColumn.class);
                aliasName = joinColumn == null ? null : isHQL ? columnField.getName() : joinColumn.name();
            }
            //构建列名语句关键字
            for (ColumnKeyWorldEnum cc : columnExtendList) {
                columnName = String.format(cc.getKeyWord(), columnName);
            }
        }
        return StrUtil.isEmpty(aliasName) ? columnName : String.format(SqlFormatConstant.AS_FORMAT, columnName, aliasName);
    }

    @Override
    public boolean needReplace(Segment t1) {
        if (t1 instanceof ColumnSegment) {
            ColumnSegment tt = (ColumnSegment) t1;
            return CollectionUtil.isNotEmpty(columnExtendList) && Objects.equals(this.getColumnFieldName(), tt.getColumnFieldName());
        }
        return false;
    }

    /**
     * 生成转换结果属性名称
     * 优先级如下 1.通过aliasName匹配 2.通过columnName匹配 3.通过columnFieldName匹配
     *
     * @return
     */
    public final String generatorResFieldName() {
        String tName = StrUtil.isNotEmpty(this.getAliasName()) ? this.getAliasName() :
                StrUtil.isNotEmpty(this.getColumnName()) ? this.getColumnName() :
                        StrUtil.isNotEmpty(this.getColumnFieldName()) ? this.getColumnFieldName() : null;
        return tName;
    }
}
